package cromosomas;

import java.text.DecimalFormat;
import java.util.Random;

/**
 * abstract class Cromosoma
 * 
 * @author Marco Gallardo Casu, Miguel Cisneros Rojas
 * 
 */
public abstract class Cromosoma {

	protected int longitud;
	protected boolean[] genes;
	protected double[] fenotipo;
	protected double aptitud;
	protected double pSeleccion;
	protected double pAcumulada;
	protected double tolerancia;

	// Metodos abstractos.

	abstract protected double[] fenotipo();

	abstract protected double evalua();

	// Publicas

	public boolean[] generarGenes() {
		boolean[] genes = new boolean[longitud];
		for (int i = 0; i < longitud; i++) {
			genes[i] = (new Random()).nextBoolean();
		}
		return genes;
	}

	// Accesoras y modificadoras.

	public boolean[] getGenes() {
		return genes;
	}

	public void setGenes(boolean[] genes) {
		this.genes = genes;
	}

	public boolean getGen(int index) {
		return genes[index];
	}

	public void setGen(int index, boolean gen) {
		genes[index] = gen;
	}

	public double getAptitud() {
		return aptitud;
	}

	public int getLongitud() {
		return longitud;
	}

	public double getpSeleccion() {
		return pSeleccion;
	}

	public void setpSeleccion(double pSeleccion) {
		this.pSeleccion = pSeleccion;
	}

	public double getpAcumulada() {
		return pAcumulada;
	}

	public void setpAcumulada(double pAcumulada) {
		this.pAcumulada = pAcumulada;
	}

	// Auxiliares.

	protected double log2(double x) {
		return Math.log10(x) / Math.log10(2);
	}

	protected double binDec(boolean[] genes, int c, int f) {
		double valor = 0.0;
		for (int i = c; i < f; i++) {
			if (genes[i]) {
				valor += Math.pow(2, f - i - 1);
			}
		}
		return valor;
	}

	protected String aptitudToString() {
		return (new DecimalFormat("#.######")).format(aptitud);
	}

	protected String genesToString() {
		String s = "";
		for (boolean b : genes) {
			s += b ? "1" : "0";
		}
		return s;
	}

	protected String fenotipoToString() {
		String s = "";
		final int LENGTH = fenotipo.length;
		for (int index = 0; index < LENGTH; index++) {
			double valor = fenotipo[index];
			DecimalFormat df = new DecimalFormat("#.######");
			s += df.format(valor);
			if (index != LENGTH - 1) {
				s += " | ";
			}
		}
		return s;
	}

	@Override
	public String toString() {
		return "Fenotipo: " + fenotipoToString() + "\nGenes: "
				+ genesToString() + "\nAptitud: " + aptitudToString();
	}

}
